package com.jinglin.component;

import com.jinglin.entity.config.AppConfig;
import com.jinglin.entity.constants.Constants;
import com.jinglin.entity.dto.SysSettingDto;
import com.jinglin.entity.dto.TokenUserInfoDto;
import com.jinglin.entity.dto.UploadingFileDto;
import com.jinglin.entity.dto.VideoPlayInfoDto;
import com.jinglin.entity.enums.DateTimePatternEnum;
import com.jinglin.entity.po.VideoInfoFilePost;
import com.jinglin.redis.RedisUtils;
import com.jinglin.utils.DateUtil;
import com.jinglin.utils.StringTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Component
public class RedisComponent {
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private AppConfig appConfig;

    public String saveCheckCode(String code) {
        String checkCodeKey = UUID.randomUUID().toString();
        redisUtils.setex(Constants.REDIS_KEY_CHECK_CODE + checkCodeKey, code, Constants.REDIS_KEY_EXPIRES_ONE_MIN * 60);
        return checkCodeKey;
    }

    public String getCheckCode(String checkCodeKey) {
        return (String) redisUtils.get(Constants.REDIS_KEY_CHECK_CODE + checkCodeKey);
    }

    public void cleanCheckCode(String checkCodeKey) {
        redisUtils.delete(checkCodeKey);
    }

    public String saveTokenInfo(TokenUserInfoDto tokenUserInfoDto) {
        String token = UUID.randomUUID().toString();
        tokenUserInfoDto.setExpireAt(System.currentTimeMillis() + Constants.REDIS_KEY_EXPIRES_DAY * 7L);
        tokenUserInfoDto.setToken(token);
        redisUtils.setex(Constants.REDIS_KEY_TOKEN_WEB + token, tokenUserInfoDto, Constants.REDIS_KEY_EXPIRES_DAY * 7);
        return token;
    }

    public TokenUserInfoDto getTokenInfo(String token) {
        return (TokenUserInfoDto) redisUtils.get(Constants.REDIS_KEY_TOKEN_WEB + token);
    }

    public String getAdminTokenAccount(String token) {
        String account = (String) redisUtils.get(Constants.REDIS_KEY_TOKEN_ADMIN + token);
        return account;
    }

    public void cleanToken(String token) {
        redisUtils.delete(Constants.REDIS_KEY_TOKEN_WEB + token);
    }

    public String saveAdminTokenInfo(String account) {
        String token = UUID.randomUUID().toString();
        redisUtils.setex(Constants.REDIS_KEY_TOKEN_ADMIN + token, account, Constants.REDIS_KEY_EXPIRES_DAY * 7);
        return token;
    }

    public String savePreVideoFileInfo(String userId, String fileName, Integer chunks) {
        String uploadId = StringTools.getRandomString(15);
        UploadingFileDto uploadingFileDto = new UploadingFileDto();
        uploadingFileDto.setFileName(fileName);
        uploadingFileDto.setUploadId(uploadId);
        uploadingFileDto.setChunks(chunks);
        // 这个ChunkIndex是指当前视频上传到了第几个分配，一开始都是0
        uploadingFileDto.setChunkIndex(0);
        String date = DateUtil.format(new Date(), DateTimePatternEnum.YYYYMMDD.getPattern());
        String filePath = date + "/" + userId + uploadId;
        String folder = appConfig.getProjectFolder()  + "/" + Constants.FILE_FOLDER_TEMP + filePath;
        File folderFile = new File(folder);
        if (!folderFile.exists()){
            folderFile.mkdirs();
        }
        // 设置的filePath只到文件夹
        uploadingFileDto.setFilePath(filePath);
        redisUtils.setex(Constants.REDIS_KEY_UPLOADING_FILE + userId + uploadId, uploadingFileDto, Constants.REDIS_KEY_EXPIRES_DAY);
        return uploadId;
    }

    public UploadingFileDto getUploadFileDto(String userId, String uploadId) {
        return (UploadingFileDto) redisUtils.get(Constants.REDIS_KEY_UPLOADING_FILE + userId + uploadId);
    }

    public SysSettingDto getSysSettingDto() {
        SysSettingDto sysSettingDto = (SysSettingDto) redisUtils.get(Constants.REDIS_KEY_SYS_SETTING);
        // 如果redis里面预先没有 系统设置信息， 那么直接new一个默认值信息
        if (sysSettingDto == null){
            sysSettingDto = new SysSettingDto();
        }
        return sysSettingDto;
    }

    public void updateUploadFileDto(String userId, UploadingFileDto fileDto) {
        redisUtils.setex(Constants.REDIS_KEY_UPLOADING_FILE + userId + fileDto.getUploadId(), fileDto, Constants.REDIS_KEY_EXPIRES_DAY);

    }
    public void delVideoFileInfo(String userId,String uploadId){
        redisUtils.delete(Constants.REDIS_KEY_UPLOADING_FILE + uploadId + uploadId);
    }

    public void addFile2DelQueue(String videoId, List<String> delFilePathList) {
        //lpush适用于需要保持顺序且可能有重复数据库的情况，比如消息队列、任务队列等
        redisUtils.lpushAll(Constants.REDIS_KEY_FILE_DEL+videoId,delFilePathList,Constants.REDIS_KEY_EXPIRES_DAY);
    }
    public List<String> getVideoFileDeleteQueue(String videoId) {
        return (List<String>) redisUtils.get(Constants.REDIS_KEY_FILE_DEL+videoId);
    }

    public void cleanDeleteVideoFileQueue(String videoId) {
        redisUtils.delete(Constants.REDIS_KEY_FILE_DEL+videoId);
    }

    public void addFile2TransferQueue(List<VideoInfoFilePost> addFileList) {
        // 所有的视频信息都可以放到这里等待转码，不区分这是谁的视频
        redisUtils.lpushAll(Constants.REDIS_KEY_FILE_TRANSFER_QUEUE,addFileList,0);
    }
    public void saveSettingDto(SysSettingDto sysSettingDto) {
        redisUtils.set(Constants.REDIS_KEY_SYS_SETTING, sysSettingDto);
    }


    public void addKeywordCount(String keyword) {
        redisUtils.zaddCount(Constants.REDIS_KEY_VIDEO_SEARCH_COUNT, keyword);
    }

    public List<String> getKeywordTop(Integer top) {
        return redisUtils.getZSetList(Constants.REDIS_KEY_VIDEO_SEARCH_COUNT, top - 1);
    }

    public void addVideoPlay(VideoPlayInfoDto videoPlayInfoDto) {
        redisUtils.lpush(Constants.REDIS_KEY_QUEUE_VIDEO_PLAY,videoPlayInfoDto,null );
    }

    public void recordVideoPlayCount(String videoId) {
        // 记录当天，此视频播放了多少次
        String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        redisUtils.incrementex(Constants.REDIS_KEY_VIDEO_PLAY_COUNT + date + ":" + videoId, Constants.REDIS_KEY_EXPIRES_DAY * 2L);
    }


    public Map<String, Integer> getVideoPlayCount(String date) {
        Map<String, Integer> videoPlayMap = redisUtils.getBatch(Constants.REDIS_KEY_VIDEO_PLAY_COUNT + date);
        return videoPlayMap;
    }
}
